package models

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlc"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"strings"
)

type FriendRelationExtendModel interface {
	UpdateGroup(ctx context.Context, userId int64, friendIds []int64, groupId int64, status int64) error
	Count(ctx context.Context, userId int64) (int64, error)
	FindList(ctx context.Context, userId, offset, limit int64) ([]*FriendRelation, error)
	UpdateStatus(ctx context.Context, userId, friendId, status1, status2 int64) error
}

func NewFriendRelationExtendModel(conn sqlx.SqlConn, c cache.CacheConf) FriendRelationExtendModel {
	return &defaultFriendRelationModel{
		CachedConn: sqlc.NewConn(conn, c),
		table:      "friend_relation",
	}
}

func (m *defaultFriendRelationModel) UpdateGroup(ctx context.Context, userId int64, friendIds []int64, groupId int64, status int64) error {
	var friendStrList []string
	for _, id := range friendIds {
		friendStrList = append(friendStrList, fmt.Sprintf("%v", id))
	}
	friendIdStr := strings.Join(friendStrList, ",")
	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set `group_id` = ?, `status` = ? where `user_id` = ? and `friend_id` in (%s)",
			m.table)
		return conn.ExecCtx(ctx, query, groupId, status, userId, friendIdStr)
	})
	return err
}

func (m *defaultFriendRelationModel) Count(ctx context.Context, userId int64) (int64, error) {
	var count int64
	query := fmt.Sprintf("select count(*) from %s where `user_id` = ? and `status` = 0", m.table)
	err := m.QueryRowNoCacheCtx(ctx, &count, query, userId)
	return count, err
}

func (m *defaultFriendRelationModel) FindList(ctx context.Context, userId, offset, limit int64) ([]*FriendRelation, error) {
	var list []*FriendRelation
	query := fmt.Sprintf("select %s from %s where `user_id` = ? and `status` = 0 and id > ? offset ? limit ?", friendRelationRows, m.table)
	err := m.QueryRowsNoCacheCtx(ctx, &list, query, userId, offset, limit)
	return list, err
}

func (m *defaultFriendRelationModel) UpdateStatus(ctx context.Context, userId, friendId, status1, status2 int64) error {
	query1 := fmt.Sprintf("update %s set status=%d where user_id=%d and friend_id=%d", m.table, status1, userId, friendId)
	query2 := fmt.Sprintf("update %s set status=%d where user_id=%d and friend_id=%d", m.table, status2, friendId, userId)
	_, err := m.ExecNoCacheCtx(ctx, query1)
	if err != nil {
		return err
	}
	_, err = m.ExecNoCacheCtx(ctx, query2)
	if err != nil {
		return err
	}
	return nil
}
